<?php

class SystemModel extends BaseModel
{

	/**
	 * Hold an instance of the class
	 * @var
	 */
	private static $_instance = null;
	
	/**
	 * A private constructor
	 * Prevents direct creation of object
	 */
	private function __construct(){
		$this->_init();
	}


	/**
	 * The singleton method
	 * @return
	 */
	public static function getInstance(){
		if (!self::$_instance instanceof self)
		self::$_instance = new self;

		return self::$_instance;
	}

	public function getOptions(){

		$options = dibi::query("SELECT name, value FROM ".TABLE_OPTIONS."")->fetchPairs("name","value");

		if(empty($options)) self::reloadOptions();

		return $options;

	}

	public function setOptionVariable($name, $value){

		if(!self::existsOption($name)) self::addOption($name);

		dibi::query("UPDATE ".TABLE_OPTIONS." SET value = %s", $value, "WHERE name = %s",$name);

	}

	public function getOptionVariable($name){

		$options = self::getOptions();

		foreach($options as $key=>$value){
			if($key==$name) return $value;
		}

		return false;

	}

	public function addOption($name){

		dibi::query("INSERT INTO ".TABLE_OPTIONS." (name) VALUES(%s)", $name);

	}

	public function saveOptions($options){

		foreach($options as $key=>$value){
			self::setOptionVariable($key, $value);
		}

	}

	public function existsOption($name){

		$exists = dibi::query("SELECT name FROM ".TABLE_OPTIONS." WHERE name = %s", $name)->fetchSingle();

		return !empty($exists) ? true : false;
	}

	public function reloadOptions(){

		$options = array("sess_exp" => "");

		foreach($options as $key=>$value){
			if(!self::existsOption($key)) self::addOption($key);
		}

	}

	public function getLanguages(){

		return dibi::query("SELECT * FROM ".TABLE_LANGUAGES."");

	}

	public function getDefaultLanguage(){

		return dibi::query("SELECT * FROM ".TABLE_LANGUAGES." WHERE `default` = %i", 1)->fetchAll();

	}

	public function getLanguage($id_language){

		return dibi::query("SELECT * FROM ".TABLE_LANGUAGES." WHERE id_language = %i", $id_language)->fetchAll();

	}
	
	public function getCurrentLanguage(){
		
		return dibi::query("SELECT * FROM ".TABLE_LANGUAGES." WHERE id_language = %i", $this->session_web->id_language)->fetchAll();
	}
	
	public function addLanguage($args){
		
		dibi::query("INSERT INTO ".TABLE_LANGUAGES."", $args);
		
	}
	
	public function editLanguage($args){
		
		$id_language = $args["id_language"];
		unset($args["id_language"]);
		dibi::query("UPDATE ".TABLE_LANGUAGES." SET", $args, "WHERE id_language = %i", $id_language);
		
	}
	
	public function deleteLanguage($id_language){
		
		dibi::query("DELETE FROM ".TABLE_LANGUAGES." WHERE id_language = %i", $id_language);
		
	}
	
	public function setLanguage($id_language){

		$this->session->admin_id_language = $id_language;

	}

	public function initLanguage(){

		if(empty($this->session->admin_id_language)){
			$lang = self::getDefaultLanguage();
			self::setLanguage($lang[0]["id_language"]);
		}

	}
	
	public function initLanguageWeb(){

		if(empty($this->session_web->id_language)){
			$lang = self::getDefaultLanguage();
			self::setLanguageWeb($lang[0]["id_language"]);
		}

	}
	
	public function setLanguageWeb($id_language){

		$this->session_web->id_language = $id_language;

	}

	public function saveMenuItem($args = array()){

		if($args["start"]==1){
			dibi::query("UPDATE ".TABLE_MENU." SET start = 0 WHERE id_language = %i", $this->session->admin_id_language);
		}

		if($args["parent"] == 0) {
			$args["parent"] = NULL;
			$last = dibi::query("SELECT `order` FROM ".TABLE_MENU." WHERE parent IS NULL ORDER BY `order` DESC")->fetchAll();
			$args["depth"] = 0;
		}else{
			$last = dibi::query("SELECT `order`, `depth` FROM ".TABLE_MENU." WHERE parent = %i", $args["parent"], "ORDER BY `order` DESC")->fetchAll();
			$parent = dibi::query("SELECT depth FROM ".TABLE_MENU." WHERE id_menu = %i", $args["parent"])->fetchAll();
			$args["depth"] = $parent[0]["depth"] + 1;
		}

		// overime zda se zmenil predek, jestli ano prepocitame poradi
		$last_access = dibi::query("SELECT parent FROM ".TABLE_MENU." WHERE id_menu = %i", $args["id_menu"])->fetchSingle();

		if($last_access!=$args["parent"] || empty($args["id_menu"])){

			if(empty($last[0]["order"])) $order = 1;
			else $order = $last[0]["order"] + 1;

			$args["order"] = $order;

		}

		if(empty($args["id_menu"])){
			$args["id_language"] = $this->session->admin_id_language;
			dibi::query("INSERT INTO ".TABLE_MENU."", $args);
		}else
		dibi::query("UPDATE ".TABLE_MENU." SET", $args, "WHERE id_menu = %i", $args["id_menu"]);

	}

	public function getMenuLeaf($parent){

		if($parent==NULL) return dibi::query("SELECT * FROM ".TABLE_MENU." WHERE parent IS NULL ORDER BY `order` ASC")->fetchAll();

		return dibi::query("SELECT * FROM ".TABLE_MENU." WHERE parent = %i", $parent, "ORDER BY `order` ASC")->fetchAll();

	}

	public function deleteMenuItem($id_menu){

		dibi::query("DELETE FROM ".TABLE_MENU." WHERE id_menu = %i", $id_menu);

	}

	public function loadMenuItemById($id_menu){

		return dibi::query("SELECT * FROM ".TABLE_MENU." WHERE id_menu = %i", $id_menu)->fetchAll();

	}
	
	public function getMenuItemByModule($id_module){
		
		$lang = $this->getCurrentLanguage();
		
		return dibi::fetchAll("SELECT * FROM ".TABLE_MENU." WHERE id_module = %i AND id_language = %i", $id_module, $lang[0]["id_language"]);
	}

	public function getModules(){

		return dibi::dataSource("SELECT * FROM ".TABLE_MODULES."");

	}
	
	public function getModuleById($id_module){
		
		return dibi::query("SELECT * FROM ".TABLE_MODULES." WHERE id_module = %i", $id_module)->fetchAll();
	}
	
	public function getBoxInMenuByIdMenu($id_menu){
		
		$boxModules = dibi::dataSource("SELECT menu.*, module.name FROM ".TABLE_BOX_IN_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS module USING(id_module) WHERE id_menu = %i", $id_menu)->fetchAll();
		$modules = $this->getModules();
		
		if(count($boxModules) != count($modules)) $boxModules = $this->autoBoxInMenuInsert($boxModules, $modules, $id_menu);
		
		return $boxModules;
	}
	
	public function saveBoxInMenu($items){
		
		foreach($items as $i){
			
			dibi::query("UPDATE ".TABLE_BOX_IN_MENU." SET enable = %i WHERE id_box_in_menu = %i", $i["enable"], $i["id_box_in_menu"]);
		}
	}
	
	public function autoBoxInMenuInsert($boxModules, $modules, $id_menu){
		
		foreach($modules as $m){
			$tmp_m[] = $m["id_module"];
		}
		
		$tmp_b = array();
		foreach($boxModules as $b){
			$tmp_b[] = $b["id_module"];
		}
		
		foreach($tmp_m as $t){
			if(!in_array($t, $tmp_b)){
				$arr[] = array(
							"id_module" => $t,
							"id_menu" => $id_menu,
							"enable" => 0
							);
			}
		}
		
		dibi::query("INSERT INTO ".TABLE_BOX_IN_MENU." %ex", $arr);
		return $this->getBoxInMenuByIdMenu($id_menu);
	}

	public function getUsers(){

		return dibi::query("SELECT * FROM ".TABLE_USERS." WHERE role != 'superAdmin'")->fetchAll();

	}

	public function loadModulesFromDir(){

		$modules = array();

		if ($handle = opendir(WWW_DIR . '/app/modules/')) {

			while (false !== ($file = readdir($handle))) {
				if($file != "." && $file != ".."){
					$name = explode(".",$file);
					$modules[]["name"] = $name[0];
				}
			}

			closedir($handle);
		}
		return $modules;

	}
	
	public function fetchModules(){
		
		return dibi::select("*")
				->from(TABLE_MODULES)
				->fetchAll();
	}
	
	public function isModulRegistered($presenter){

		$is = dibi::query("SELECT name FROM ".TABLE_MODULES." WHERE presenter = %s", $presenter)->fetchAll();

		return empty($is) ? false : true;

	}

	public function registerModule($args){

		return dibi::insert(TABLE_MODULES, $args)->execute(dibi::IDENTIFIER);

	}
	
	public function registerSearch($search, $id_module){
		
		$args = array("id_module" => $id_module, "data" => serialize($search));
		
		return dibi::insert(TABLE_SEARCH, $args)->execute();
		
	}
	
	public function isSearchRegistered($id_module){
		
		$exists = dibi::select("id_module")
					->from(TABLE_SEARCH)
					->where("id_module = %i", $id_module)
					->fetchSingle();
					
		return empty($exists) ? false : true;
	}
	
	public function moduleAddSql($sql){

		dibi::query($sql);

	}

	public function toggleModule($id_module){

		$active = dibi::query("SELECT active FROM ".TABLE_MODULES." WHERE id_module = %i", $id_module)->fetchSingle();

		$active = $active == 1 ? 0 : 1;

		dibi::query("UPDATE ".TABLE_MODULES." SET active = %i", $active,"WHERE id_module = %i", $id_module);

	}

	public function loadUser($id_user){

		return dibi::query("SELECT * FROM ".TABLE_USERS." WHERE id_user = %i", $id_user)->fetchAll();

	}

	public function getMenu($iter = FALSE, $id_menu=FALSE){

		if(!$id_menu) $menu = dibi::query("SELECT menu.*, modules.presenter, modules.params, modules.name AS module_name FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) WHERE parent IS NULL AND id_language = %i ORDER BY `order` ASC", $this->session->admin_id_language)->fetchAll();
		else $menu = dibi::query("SELECT menu.*, modules.presenter, modules.params, modules.name AS module_name FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) WHERE parent IS NULL AND id_language = %i", $this->session->admin_id_language,"AND id_menu = %i", $id_menu,"ORDER BY `order` ASC")->fetchAll();
		
		foreach($menu as &$m){
			$iterator = "";
			self::getMenuChildrens($m, $iterator, $iter);
		}

		unset($m);

		return $menu;
	}

	public function getMenuWeb($iter = FALSE, $id_menu=FALSE){

		if(!$id_menu) $menu = dibi::query("SELECT menu.*, modules.presenter, modules.params, modules.name AS module_name, lang.default, lang.abbr FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) JOIN ".TABLE_LANGUAGES." AS lang USING(id_language) WHERE parent IS NULL AND id_language = %i ORDER BY `order` ASC", $this->session_web->id_language)->fetchAll();
		else $menu = dibi::query("SELECT menu.*, modules.presenter, modules.params, modules.name AS module_name, lang.default, lang.abbr FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) JOIN ".TABLE_LANGUAGES." AS lang USING(id_language) WHERE parent IS NULL AND id_language = %i", $this->session_web->id_language,"AND id_menu = %i", $id_menu,"ORDER BY `order` ASC", $this->session_web->id_language)->fetchAll();

		foreach($menu as &$m){
			$iterator = "";
			self::getMenuChildrens($m, $iterator, $iter);
		}

		unset($m);

		return $menu;
	}

	public function getMenuChildrens(&$parent, &$iterator, &$iter){

		$parent["sub"] = dibi::query("SELECT menu.*, modules.presenter, modules.params, modules.name AS module_name, lang.default, lang.abbr FROM ".TABLE_MENU."  AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) JOIN ".TABLE_LANGUAGES." AS lang USING(id_language) WHERE parent = %i", $parent["id_menu"],"ORDER BY `order` ASC")->fetchAll();

		if(!empty($parent["sub"])){

			foreach($parent["sub"] as $s){
				if($iter) $iterator = str_repeat("-", $s["depth"]);
				$s["name"] = $iterator.$s["name"];
				self::getMenuChildrens($s, $iterator, $iter);
			}
		}

	}

	public function getMenuToSelect(){

		$menu = self::getMenu();

		$out = array();

		foreach($menu as $item){
			$iterator = "";
			$out[$item["id_menu"]] = $item["name"];

			if(!empty($item["sub"])){
				self::getSubMenuToSelect($item["sub"], $out, $iterator);
			}

		}

		return $out;
	}

	public function getSubMenuToSelect($sub, &$out, &$iterator){

		
		foreach($sub as $s){
			$iterator = str_repeat("-", $s["depth"]);
			$out[$s["id_menu"]] = $iterator.$s["name"];
			if(!empty($s["sub"])) self::getSubMenuToSelect($s["sub"], $out, $iterator);
		}
	}

	public function getMenuForRouter($admin=FALSE){

		if($admin==false) $menu = self::getMenuWeb();
		else $menu = self::getMenu();

		$out = array();

		foreach($menu as &$item){
			$out[] = $item;

			//$item->name_seo_router = $item["name_seo"];
			$par_name = $item["name_seo"];
			if(!empty($item["sub"])){
				self::getSubMenuForRouter($item["sub"], $out, $par_name);
			}

		}

		return $out;

	}

	public function getSubMenuForRouter($sub, &$out, $par_name){

		if(substr($par_name,0, -1)!="/") $par_name .= "/";

		foreach($sub as $s){
			$s->name_seo_router = $par_name;

			$out[] = $s;
			if(!empty($s["sub"])) self::getSubMenuForRouter($s["sub"], $out, $par_name.$s["name_seo"]);
		}

	}

	public function getMenuItemById($id){

		return dibi::query("SELECT *, modules.presenter FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module)  WHERE id_menu = %i", $id)->fetchAll();

	}

	public function getMenuItemByname($name){

		return dibi::query("SELECT menu.*, modules.presenter FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) WHERE name_seo = %s", $name)->fetchAll();

	}
	
	public function getMenuItemBynameAndParent($name, $id_parent = false){

		return dibi::query("SELECT menu.*, modules.presenter FROM ".TABLE_MENU." AS menu LEFT JOIN ".TABLE_MODULES." AS modules USING(id_module) WHERE name_seo = %s AND parent = %i", $name, $id_parent)->fetchAll();

	}

	public function getModulesToSelect(){

		$modules = self::getModules()->where("active = 1")->select("*");

		$out = array();
		foreach($modules as $module){
			$out[$module["id_module"]] = $module["name"];
		}

		return $out;
	}

	public function saveUser($args){

		dibi::query("INSERT INTO ".TABLE_USERS."", $args);

	}

	public function editUser($args){

		dibi::query("UPDATE ".TABLE_USERS." SET", $args,"WHERE id_user = %i", $args["id_user"]);

	}

	public function addUser($args){

		dibi::query("INSERT INTO ".TABLE_USERS."", $args);

	}

	public function deleteUser($id_user){

		dibi::query("DELETE FROM ".TABLE_USERS." WHERE id_user = %i", $id_user);

	}
	
	public function getMainMenuItem(){
		
		$lang = $this->getCurrentLanguage();
		
		return dibi::query("SELECT * FROM ".TABLE_MENU." WHERE start = %i AND id_language = %i", 1, $lang[0]['id_language'])->fetch();
	}
	
	public function saveDirectory($name, $id_parent){
		
		$parent = dibi::query("SELECT path, name FROM ".TABLE_FILES." WHERE id_file = %i", $id_parent)->fetchAll();
		
		if(!is_numeric($id_parent) || $id_parent < 1) $id_parent = NULL;
		
		$name_seo = $this->createSeo($name);
		$path = (!empty($parent[0]["name"]) ? $parent[0]["path"].$parent[0]["name"]."/" : "");
		$arr = array(
					"parent" => $id_parent,
					"type" => "DIR",
					"name" => $name_seo,
					"path" => $path,
					"custom_name" => $name
					);

		$ok = mkdir("upload/".$parent[0]["path"].$parent[0]["name"]."/".$name_seo."/", 0777); // TODO upravit predchozi cestu
		if($ok) dibi::query("INSERT INTO ".TABLE_FILES, $arr);
	}
	
	public function getFileById($id_file){
		
		return dibi::query("SELECT * FROM ".TABLE_FILES." WHERE id_file = %i", $id_file)->fetchAll();
	}
	
	public function getFiles($id_directory = NULL){
		
		$directory_parent = dibi::query("SELECT parent, path, name FROM ".TABLE_FILES." WHERE id_file = %i", $id_directory)->fetchAll();
		
		if($id_directory == NULL || $id_directory == 0){
			$files = dibi::query("SELECT f.*, (SELECT SUM(size) FROM ".TABLE_FILES." WHERE path LIKE 'f.name%') AS sized FROM ".TABLE_FILES." AS f WHERE parent IS NULL ORDER BY type DESC")->fetchAll();
		}
		else{
			$files = dibi::query("SELECT f.*, (SELECT SUM(size) FROM ".TABLE_FILES." WHERE path LIKE 'f.name%') AS sized FROM ".TABLE_FILES." AS f WHERE parent = %i ORDER BY type DESC", $id_directory)->fetchAll();
		}
		
		// FIXME nahradit v sql dotaze
		foreach($files as &$f){
			$f["sized"] = dibi::query("SELECT SUM(size) FROM ".TABLE_FILES." WHERE path LIKE %s", "%".$f["name"]."%")->fetchSingle();
		}
		unset($f);
		
		return array("files" => $files, "id_directory" => $id_directory, "id_directory_parent" => $directory_parent[0]["parent"], "path" => $directory_parent[0]["path"].$directory_parent[0]["name"]);
	}
	
	public function deleteDirectory($id_file, $base){
		
		$file = dibi::query("SELECT path, name, th_name FROM ".TABLE_FILES." WHERE id_file = %i", $id_file)->fetchAll();
		
		$path = $_SERVER['DOCUMENT_ROOT'] . $base . "upload/".$file[0]["path"].$file[0]["name"];
		$path_th = $_SERVER['DOCUMENT_ROOT'] . $base . "upload/".$file[0]["path"].$file[0]["th_name"];
		
		if(is_dir($path) && $path != $_SERVER['DOCUMENT_ROOT'] . $base . "upload/"){
			$this->removeDir($path."/");
			rmdir($path."/");
		}else{
			unlink($path);
			unlink($path_th);
		}
		
		dibi::query("DELETE FROM ".TABLE_FILES." WHERE id_file = %i", $id_file);
	}
	
	public function deleteFile($id_file){
		
		$file = dibi::query("SELECT path, custom_name FROM ".TABLE_FILES." WHERE id_file = %i", $id_file)->fetchAll();
		
		$path = "upload/".$file[0]["path"].$file[0]["custom_name"]."/";
		
		$this->removeDir($path);
		rmdir($path);
		dibi::query("DELETE FROM ".TABLE_FILES." WHERE id_file = %i", $id_file);
	}
	
	public function saveFiles($files, $id_parent){
		
		$parent = dibi::query("SELECT path, name FROM ".TABLE_FILES." WHERE id_file = %i", $id_parent)->fetchAll();
		
		$path = (!empty($parent[0]["name"]) ? $parent[0]["path"].$parent[0]["name"]."/" : "");
		foreach($files as $file){
			$this->saveFile($file["name"], $path, $id_parent, $file["type"], $file["size"]);
		}
	}
	
	public function saveFile($file, $path, $parent, $type, $size){
		
		if(empty($parent)) $parent = NULL;
		
		$file_custom = str_replace($type, "", $file);
		$file = $this->createSeoFile($file);
		
		$arr = array(
					"parent" => $parent,
					"type" => $type,
					"name" => $file,
					"path" => $path,
					"size" => $size,
					"custom_name" => $file_custom
					);
		
		dibi::query("INSERT INTO ".TABLE_FILES, $arr);
		$id_file = dibi::insertId();
		
		// vytvoreni nahledu pokud je soubor obrazek
		$type = strtolower($type);
		$type = str_replace(".", "", $type);
		
		$obrazek = array("gif", "png", "jpg");
		
		if(in_array($type, $obrazek) == true){
			$this->createThumbFromFile($id_file);
		}
	}
	
	public function createThumbFromFile($id_file){
		
		$file = dibi::query("SELECT * FROM ". TABLE_FILES." WHERE id_file = %i", $id_file)->fetchAll();
		
		$path = WWW_DIR . "/upload/" . $file[0]["path"];
		
		$file_path = $path . $file[0]["name"];
		
		if(file_exists($file_path)){
			$image = Image::fromFile($file_path);
			$image2 = clone $image;
			// TODO dodelat do nastaveni systemu zmenu velikosti obrazku
			$file_th = "th_sys_".$file[0]["name"];
			$file2 = "th_news_".$file[0]["name"];
			
			$image->resize("160", NULL);
			$image->save($path . $file_th, 90);
			
			$image2->resize(379, 252, Image::STRETCH);
			$image2->save($path . $file2, 90);
			
			dibi::query("UPDATE ".TABLE_FILES." SET th_name = %s WHERE id_file = %i", $file_th, $id_file);
		}
		
		
	}
	
}

?>